package com.ls.blog.config;

import com.ls.blog.security.filter.CaptchaFilter;
import com.ls.blog.security.filter.JwtAuthenticationFilter;
import com.ls.blog.security.handler.AccessDeniedHandlerImpl;
import com.ls.blog.security.handler.AuthenticationEntryPointImpl;
import com.ls.blog.security.handler.AuthenticationFailHandlerImpl;
import com.ls.blog.security.handler.LogoutSuccessHandlerIml;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


/**
 * Security配置类
 *
 * @author 11921
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    public static final String[] URL_WHITELIST = {

            "/webjars/**",
            "/favicon.ico",
            "/captcha",
            "/login",
            "/logout",
            "/user/register"
    };


    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    private AuthenticationFailHandlerImpl authenticationFailHandler;
    @Autowired
    private CaptchaFilter captchaFilter;
    @Autowired
    private AuthenticationEntryPointImpl authenticationEntryPointIml;
    @Autowired
    private AccessDeniedHandlerImpl accessDeniedHandlerIml;
    @Autowired
    private LogoutSuccessHandlerIml logoutSuccessHandler;

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
        return new JwtAuthenticationFilter(authenticationManager());
    }


    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * 配置权限
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {


        // 关闭csrf拦截
        http.cors().and().csrf().disable();
        // 认证
        http.formLogin()
                .successHandler(authenticationSuccessHandler)
                .failureHandler(authenticationFailHandler)
                .and()
                .logout()
                .logoutSuccessHandler(logoutSuccessHandler);

        // 禁用session
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().headers().cacheControl();
        // 配置白名单
        http.authorizeRequests()
                .antMatchers(URL_WHITELIST).permitAll()
                .anyRequest() .authenticated()
         // 异常处理
         .and()
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPointIml)
                .accessDeniedHandler(accessDeniedHandlerIml)
        // 配置自定义的过滤器
        .and()
                .addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class)
                .addFilter(jwtAuthenticationFilter());
    }

    /*
     * 解决Security访问Swagger2被拦截的问题；
     * */
    @Override
    public void configure(WebSecurity web) throws Exception {
        // allow Swagger URL to be accessed without authentication
        web.ignoring().antMatchers(
                "/swagger-ui.html",
                "/v2/api-docs",
                "/swagger-resources/configuration/ui",
                "/swagger-resources",
                "/swagger-resources/configuration/security",
                "/swagger-resources/**",
                "/webjars/**"

        );
    }


}
